<?php

namespace App\Exports;


use App\Service\Common\ExportService;
use Box\Spout\Common\Exception\InvalidArgumentException;
use Box\Spout\Common\Exception\IOException;
use Box\Spout\Writer\Exception\WriterNotOpenedException;
use Exception;
use Illuminate\Support\Collection;
use OSS\Core\OssException;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;

abstract class BaseExport
{
    protected ExportService $exportService;

    /**
     * @throws NotFoundExceptionInterface
     * @throws WriterNotOpenedException
     * @throws ContainerExceptionInterface
     * @throws IOException
     * @throws Exception
     */
    public function __construct(string $fileName = "", array $header = [], string $suffix = "csv")
    {
        $fileName = empty($fileName) ? $this->getFileName() : $fileName;
        $header   = empty($header) ? $this->getHeader() : $header;

        if (empty($fileName || empty($header))) {
            throw new Exception("文件名或导出excel头信息缺失");
        }
        $this->exportService = new ExportService($fileName, $header, $suffix);
    }

    /**
     * @param bool $delete
     * @return $this
     */
    public function setDeleteLocalFile(bool $delete = false): BaseExport
    {
        $this->exportService->setDeleteLocalFile($delete);
        return $this;
    }

    /**
     * @param array|Collection $contents
     * @return BaseExport
     * @throws IOException
     * @throws InvalidArgumentException
     * @throws WriterNotOpenedException
     */
    public function writeContents($contents): BaseExport
    {
        $this->exportService->writeContents(is_array($contents) ? $contents : $contents->toArray());
        return $this;
    }

    /**
     * @return array
     * @throws OssException
     */
    public function ossExport(): array
    {
        return $this->exportService->ossExport();
    }

    /**
     * 获取头部信息
     *
     * @return array
     */
    abstract function getHeader(): array;

    /**
     * 获取文件名信息
     *
     * @return string
     */
    abstract function getFileName(): string;
}
